package miage.rest.resource.candidature;

import com.thoughtworks.xstream.XStream;
import miage.rest.db.Database;
import miage.rest.routing.UriTemplateFinder;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import miage.rest.model.Statut;
import miage.rest.xml.XstreamRepresentation;
import miage.rest.form.Form;
import miage.rest.model.Candidature;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Put;
import miage.rest.resource.ResourceError;
import miage.rest.validation.IntegerRangeValidator;
import miage.rest.validation.IntegerValidator;
import miage.rest.validation.LongRangeValidator;
import miage.rest.xml.xstream.converter.HrefConverter;

/**
 *
 * @author Lou
 */
public class StatutResource extends ServerResource {

    private final Database database;
    private UriTemplateFinder uriTemplateFinder;
    private Candidature candidature;
    private final String sqlCandidature = "SELECT id_candidature FROM candidature WHERE id_candidature = ?";

    public StatutResource(Database database, UriTemplateFinder uriTemplateFinder) {
        super();
        this.database = database;
        this.uriTemplateFinder = uriTemplateFinder;
    }

    /** Initialisation de la ressource a partir de la chaine d'url */
    @Override
    protected void doInit() throws ResourceException {
        Long idCandidature;
        
        String idCandidatureAttribute =getRequest().getAttributes().get("idCandidature").toString();
        //Validation de l'id de la candidature
        LongRangeValidator longRangeValidator = new LongRangeValidator(1l, null);
        //Validation de l'id de la session
        if (longRangeValidator.isValid(idCandidatureAttribute)) {
                idCandidature = Long.parseLong(idCandidatureAttribute);
        } else {
                getResponse().setEntity(ResourceError.getNewRepresentation("invalidCandidatureId"));
                throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
        }
        //Recuperation de la candidature
        try{
            candidature = database.fetchRow(sqlCandidature, Candidature.class, idCandidature);
            if(candidature == null){
                setExisting(false);
            }
        }catch(SQLException e){
            throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e);
        }
    }

    @Get
    public Representation doGet() throws Exception {
        Representation response = null;
        String sqlStatut = "SELECT candidature.id_statut, nomstatut FROM candidature, statut WHERE candidature.id_candidature = " + candidature.getIdCandidature() + " AND candidature.id_statut = statut.id_statut";

        Statut statut = (Statut) database.fetchRow(sqlStatut, Statut.class);

        if(statut == null){
            setStatus(Status.SERVER_ERROR_INTERNAL);
            response = ResourceError.getNewRepresentation("statut de la cancicature non trouvée");
        }else{
            response = new XstreamRepresentation<Statut>(statut);
            XStream xstream = ((XstreamRepresentation) response).getXstream();
        }
        return response;
    }

    /** Reponse a une requete PUT
     * Modification du statut d'une candidature
     * @param entity
     * @return
     * @throws IOException
     */
    @Put
    public Representation doPut(Representation entity) throws Exception {
        List<ResourceError> errors = new ArrayList<ResourceError>();
        Representation response = null;
        Form form = new Form(entity);
        form.addValidators("statut", new IntegerValidator(), new IntegerRangeValidator(0, 100));
        if(!form.isValid()){
           setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
           for(String msg : form.getMessages())
                errors.add(new ResourceError(msg));
        }else{
            String sqlUpdateCandidature = "UPDATE candidature SET id_statut = ? WHERE id_candidature = ?";
            database.update(sqlUpdateCandidature, Integer.parseInt(form.getFirstValue("statut")), candidature.getIdCandidature());
            candidature = database.fetchRow(sqlCandidature, Candidature.class, candidature.getIdCandidature());
            response = new XstreamRepresentation<Candidature>(candidature);
            XStream xstream = ((XstreamRepresentation) response).getXstream();
                        xstream.registerConverter(new HrefConverter(
                                Candidature.class,
                                xstream.getConverterLookup(),
                                uriTemplateFinder.find(CandidatureResource.class)));
        }
            
        
        if(!errors.isEmpty())
            response = ResourceError.getNewRepresentation(errors);
        return response;
    }
}
